1. Field of the Invention
This invention relates generally to computer systems, and, more particularly, to structures and methods for providing access protection for computer system components.
2. Description of the Related Art
A typical computer system includes a memory hierarchy in order to obtain a relatively high level of performance at relatively low cost. Instructions of several different software programs are typically stored on a relatively large but slow non-volatile storage unit (e.g., a disk drive unit). When a user selects one of the programs for execution, the instructions of the selected program are copied into a main memory unit, and a central processing unit (CPU) obtains the instructions of the selected program from the main memory unit. The well-known virtual memory management technique allows the CPU to access data structures larger in size than that of the main memory unit by storing only a portion of the data structures within the main memory unit at any given time. Remainders of the data structures are stored within the relatively large but slow non-volatile storage unit, and are copied into the main memory unit only when needed.
Virtual memory is typically implemented by dividing an address space of the CPU into multiple blocks called page frames or “pages.” Only data corresponding to a portion of the pages is stored within the main memory unit at any given time. When the CPU generates an address within a given page, and a copy of that page is not located within the main memory unit, the required page of data is copied from the relatively large but slow non-volatile storage unit into the main memory unit. In the process, another page of data may be copied from the main memory unit to the non-volatile storage unit to make room for the required page.
The popular 80x86 (x86) processor architecture includes specialized hardware elements to support a protected virtual address mode (i.e., a protected mode). FIGS. 1-3 will now be used to describe how an x86 processor implements both virtual memory and memory protection features. FIG. 1 is a diagram of a well-known linear-to-physical address translation mechanism 100 of the x86 processor architecture. Address translation mechanism 100 is embodied within an x86 processor, and involves a linear address 102 produced within the x86 processor, a page table directory (i.e., a page directory) 104, multiple page tables including a page table 106, multiple page frames including a page frame 108, and a control register 3 (CR3) 110. Page directory 104 and the multiple page tables are paged memory data structures created and maintained by operating system software (i.e., an operating system). Page directory 104 is always located within a memory (e.g., a main memory unit). For simplicity, page table 106 and page frame 108 will also be assumed to reside in the memory.
As indicated in FIG. 1, linear address 102 is divided into three portions in order to accomplish the linear-to-physical address translation. The highest ordered bits of CR3 110 are used to store a page directory base register. The page directory base register is a base address of a memory page containing page directory 104. Page directory 104 includes multiple page directory entries, including a page directory entry 112. An upper “directory index” portion of linear address 102, including the highest ordered or most significant bits of linear address 102, is used as an index into page directory 104. Page directory entry 112 is selected from within page directory 104 using the page directory base register of CR3 110 and the upper “directory index” portion of linear address 102.
FIG. 2 is a diagram of a page directory entry format 200 of the x86 processor architecture. As indicated in FIG. 2, the highest ordered (i.e., most significant) bits of a given page directory entry contain a page table base address, where the page table base address is a base address of a memory page containing a corresponding page table. The page table base address of page directory entry 112 is used to select the corresponding page table 106.
Referring back to FIG. 1, page table 106 includes multiple page table entries, including a page table entry 114. A middle “table index” portion of linear address 102 is used as an index into page table 106, thereby selecting page table entry 114. FIG. 3 is a diagram of a page table entry format 300 of the x86 processor architecture. As indicated in FIG. 3, the highest ordered (i.e., most significant) bits of a given page table entry contain a page frame base address, where the page frame base address is a base address of a corresponding page frame.
Referring back to FIG. 1, the page frame base address of page table entry 114 is used to select corresponding page frame 108. Page frame 108 includes multiple memory locations. A lower or “offset” portion of linear address 102 is used as an index into page frame 108. When combined, the page frame base address of page table entry 114 and the offset portion of linear address 102 produce the physical address corresponding to linear address 102, and indicate a memory location 116 within page frame 108. Memory location 116 has the physical address resulting from the linear-to-physical address translation.
Regarding the memory protection features, page directory entry format 200 of FIG. 2 and page table entry format 300 of FIG. 3 include a user/supervisor (U/S) bit and a read/write (R/W) bit. The contents of the U/S and R/W bits are used by the operating system to protect corresponding page frames (i.e., memory pages) from unauthorized access. U/S=0 is used to denote operating system memory pages, and corresponds to a “supervisor” level of the operating system. The supervisor level of the operating system corresponds to current privilege level 0 (CPL0) of software programs and routines executed by the x86 processor. (The supervisor level may also correspond to CPL1 and/or CPL2 of the x86 processor.) U/S=1 is used to indicate user memory pages, and corresponds to a “user” level of the operating system. The user level of the operating system corresponds to CPL3 of the x86 processor. (The user level may also correspond to CPL1 and/or CPL2 of the x86 processor.)
The R/W bit is used to indicate types of accesses allowed to the corresponding memory page. R/W=0 indicates the only read accesses are allowed to the corresponding memory page (i.e., the corresponding memory page is “read-only”). R/W=1 indicates that both read and write accesses are allowed to the corresponding memory page (i.e., the corresponding memory page is “read-write”).
During the linear-to-physical address translation operation of FIG. 1, the contents of the U/S bits of page directory entry 112 and page table entry 114, corresponding to page frame 108, are logically ANDed determine if the access to page frame 108 is authorized. Similarly, the contents of the R/W bits of page directory entry 112 and page table entry 114 are logically ANDed to determine if the access to page frame 108 is authorized. If the logical combinations of the U/S and R/W bits indicate the access to page frame 108 is authorized, memory location 116 is accessed using the physical address. On the other hand, if the logical combinations of the U/S and R/W bits indicate the access to page frame 108 is not authorized, memory location 116 is not accessed, and a protection fault indication is signaled.
Unfortunately, the above described memory protection mechanisms of the x86 processor architecture are not sufficient to protect data stored in the memory. For example, any software program or routine executing at the supervisor level (e.g., having a CPL of 0) can access any portion of the memory, and can modify (i.e., write to) any portion of the memory that is not marked “read-only” (R/W=0). In addition, by virtue of executing at the supervisor level, the software program or routine can change the attributes (i.e., the U/S and R/W bits) of any portion of the memory. The software program or routine can thus change any portion of the memory marked “read-only” to “read-write” (R/W=1), and then proceed to modify that portion of the memory.
The protection mechanisms of the x86 processor architecture are also inadequate to prevent errant or malicious accesses to the memory by hardware devices operably coupled to the memory. It is true that portions of the memory marked “read-only” cannot be modified by write accesses initiated by hardware devices (without the attributes of those portions of the memory first being changed as described above). It is also true that software programs or routines (e.g., device drivers) handling data transfers between hardware devices and the memory typically execute at the user level (e.g., CPL3), and are not permitted access to portions of the memory marked as supervisor level (U/S=0). However, the protection mechanisms of the x86 processor architecture cover only device accesses to the memory performed as a result of instruction execution (i.e., programmed input/output). A device driver can program a hardware device having bus mastering or DMA capability to transfer data from the device into any portion of the memory accessible by the hardware device. For example, it is relatively easy to program a floppy disk controller to transfer data from a floppy disk directly into a portion of the memory used to store the operating system.
Moreover, the protection mechanisms of the x86 processor architecture do not address device-to-device accesses. All components of a computer system, including hardware devices, are typically operably coupled to one another in order to facilitate communication. During system initialization (i.e., “boot up”), the CPU executes instructions which configure (i.e., program) the hardware devices to perform desired functions. During normal operation of the computer system, the CPU and the hardware devices access one another using established protocols. However, malicious device driver software may program a first hardware device, having bus mastering or DMA capability, to access a second hardware device in order to obtain confidential information from the second hardware device, or to alter a programmed function of the second hardware device. Such access may even result in the programming of the second hardware device to operate in a way that causes physical damage to the second hardware device.